package com.wits.qso.web.controller;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springside.modules.web.Servlets;

import com.wits.comet.chat.common.CometCommand;
import com.wits.comet.chat.common.CometDomain;
import com.wits.comet.chat.service.CometContext;
import com.wits.comet.chat.service.CurrentLoginUser;
import com.wits.platform.common.constants.WebConstants;
import com.wits.platform.common.utils.DateUtil;
import com.wits.platform.common.utils.PageUtil;
import com.wits.platform.common.utils.StringUtil;
import com.wits.platform.service.account.ShiroUser;
import com.wits.platform.web.controller.BaseController;
import com.wits.platform.web.mvc.AjaxResult;
import com.wits.platform.web.mvc.PageParam;
import com.wits.qso.common.enumerate.BusinessType;
import com.wits.qso.common.enumerate.GroupStatus;
import com.wits.qso.common.enumerate.HelpQueStatus;
import com.wits.qso.common.enumerate.MemberStatus;
import com.wits.qso.entity.Attachment;
import com.wits.qso.entity.Btable;
import com.wits.qso.entity.DiscussionGroup;
import com.wits.qso.entity.DiscussionMember;
import com.wits.qso.entity.DiscussionMemberPK;
import com.wits.qso.entity.HelpQue;
import com.wits.qso.entity.Student;
import com.wits.qso.entity.Teacher;
import com.wits.qso.entity.VmUser;
import com.wits.qso.service.AttachmentService;
import com.wits.qso.service.BtableDaoService;
import com.wits.qso.service.DiscussionGroupService;
import com.wits.qso.service.DiscussionMemberService;
import com.wits.qso.service.GroupCache;
import com.wits.qso.service.HelpQueService;
import com.wits.qso.service.InstructService;
import com.wits.qso.service.StudentService;
import com.wits.qso.service.TeacherService;
import com.wits.qso.service.VmUserService;

/**
 * 
 * @see 指导
 *
 */
@Controller
@RequestMapping(value = "/qso/instruct")
public class InstructController extends BaseController{
	
	@Autowired
	private HelpQueService helpQueService;

	@Autowired
	private DiscussionGroupService discussionGroupService;
	
	@Autowired
	private DiscussionMemberService discussionMemberService;

	@Autowired
	private TeacherService teacherService;
	
	@Autowired
	private StudentService studentService;
	
	@Autowired
	private BtableDaoService btableDaoService;
	
	@Autowired
	private InstructService instructService;
	
	@Autowired
	private AttachmentService attachmentService;
	
	@Autowired
	private VmUserService vmUserService;
	
	@RequestMapping(value="/toInstructMain")
	public String toInstructMain(){
		return "qso/instruct/list";
	}
	
	
	/**
	 * 
	 * @see 查询 当前课程的问题
	 * @return
	 */
	@RequestMapping(value="/questionList")
	@ResponseBody
	public Object questionList(Model model,@ModelAttribute("page") PageParam page, HttpServletRequest req){
		Page<HelpQue> listPage=null;
		String userId=this.getCurrentUserId();
		Btable btable=btableDaoService.findByTeaUserIdAndLessonTime(userId, DateUtil.getNow());
		if(btable!=null){
			Map<String, Object> searchParams = Servlets.getParametersStartingWith(req, "search_");
			searchParams.put("EQ_courseId", btable.getCouid().getId());//设置课程id
			listPage = helpQueService.findPage(HelpQue.class,searchParams, page);
		}
		return PageUtil.toAjaxPageResult(listPage);
	}
	
	
	/**
	 * 拒绝回答 提问
	 * @param ids
	 * @return
	 */
    @RequestMapping(value = "/refuseQuestion")
    @ResponseBody
	public Object refuseQuestion(@RequestParam("userIds") String userIds,@RequestParam("hpqIds") String hpqIds) {
    	ShiroUser user=this.getCurrentUser();
		try {
			String[] idArr=StringUtils.split(hpqIds,",");
			if(idArr.length>0){
				helpQueService.updateHpqStatus(idArr,HelpQueStatus.DL);
				List<String> memberList=new ArrayList<String>();
				Collections.addAll(memberList, StringUtils.split(userIds,","));
				//通知组内学生老师拒绝回答问题
	    		instructService.sendNotify(CometDomain.main,CometCommand.refuseQuestion,user, memberList);
	    		//通知老师检查问题提示灯
				instructService.sendNotify(CometDomain.main, CometCommand.checkWaitQuestion,user.getId());
			}
			return ajaxDoneSuccess(this.getText("default.success"));
		} catch (Exception e) {
			return ajaxDoneError(this.getText("default.failed"),e);
		}
	}
    
    /**
     * 完成提问
     */
    @RequestMapping(value="/finishQuestion")
    @ResponseBody
    public AjaxResult finishQuestion(@RequestParam("groupId") String groupId,@RequestParam("ids") String ids){
    	ShiroUser user=this.getCurrentUser();
		try {
			String[] idArr=StringUtils.split(ids,",");
			if(idArr==null || idArr.length==0){
				DiscussionGroup group=discussionGroupService.getOne(groupId);
				if(group!=null){
					idArr=StringUtils.split(group.getHelpIds(),",");
				}
			}
			discussionGroupService.updateGroupStatusAndQuestionStatus(groupId, GroupStatus.close, idArr, HelpQueStatus.CO);
			List<String> memberList=discussionMemberService.findMemberIdByGroupIdAndNotEqStatus(groupId, MemberStatus.deleted.value());
			//通知组内学生解答完成
    		instructService.sendNotify(CometDomain.main,CometCommand.finishQuestion,groupId, user, memberList);
    		//通知老师检查问题提示灯
			instructService.sendNotify(CometDomain.main, CometCommand.checkWaitQuestion,user.getId());
			return ajaxDoneSuccess(this.getText("default.success"));
		} catch (Exception e) {
			return ajaxDoneError(this.getText("default.failed"),e);
		}
    }
    
    
    /**
     * 
     * 指导页面(只有老师有权利进入)
     * @param model
     * @param groupId
     * @return
     */
	@RequestMapping(value="/toInstruct/{groupId}")
	public String toInstruct(Model model,@PathVariable(value="groupId") String groupId){
		ShiroUser user=this.getCurrentUser();
		DiscussionGroup group=discussionGroupService.getOne(groupId);
		model.addAttribute(groupId);
		String vmUserId=group.getVmUserId();
		VmUser vu=vmUserService.findByUserId(vmUserId);
		if(vu==null){
			//model.addAttribute(MESSAGES_KEY,vmUserId+ ":没有分配虚拟机");
			logger.info(vmUserId+ ":没有分配虚拟机");
		}
		
		List<String> memberIdList=discussionMemberService.findMemberIdByGroupIdAndNotEqStatus(groupId, MemberStatus.deleted.value());
		//推送消息到在线用户
		instructService.sendNotify(CometDomain.main,CometCommand.instruct,group.getId(), user, memberIdList);
		//通知老师检查问题提示灯
		instructService.sendNotify(CometDomain.main, CometCommand.checkWaitQuestion,user.getId());
    	model.addAttribute("vu",vu);
		return "qso/instruct/instruct";
	}
	
	/**
	 * @see 开启一个新的讨论组
	 * @param model
	 * @param command
	 * @param topic
	 * @param stuIds
	 * @return
	 */
	@RequestMapping(value = "/openDiscussion ")
	@ResponseBody
	public Object openDiscussion(
			@RequestParam(value = "vmUserId") String vmUserId,
			@RequestParam(value = "vmUserName") String vmUserName,
			@RequestParam(value = "topic") String topic,
			@RequestParam(value = "stuIds") String stuIds,
			@RequestParam(value = "hpqIds")  String hpqIds) {

		ShiroUser user = this.getCurrentUser();
		Teacher teacher = teacherService.findByUserId(user.getId());
		if(teacher==null){
			return ajaxDoneError("指导老师信息不存在!");
		}
		DiscussionGroup group=new DiscussionGroup();
		group.setVmUserId(vmUserId); //连接虚机学生(对应的user Id)
		group.setVmUserName(vmUserName);
		group.setTeaId(teacher.getTerId());
		group.setTeaName(teacher.getTerName());
		group.setTopic(topic);
		group.setDateCre(DateUtil.getNow());
		group.setUserCre(user.getId());
		group.setStatus(GroupStatus.open.value());
		group.setHelpIds(hpqIds);
		List<String> memberList=new ArrayList<String>();
		Collections.addAll(memberList, StringUtils.split(stuIds,","));
		memberList.add(user.getId());//把老师也加到讨论组中;


		List<String> hpqIdList=new ArrayList<String>();
		Collections.addAll(hpqIdList,StringUtils.split(hpqIds,","));
        try{
        	discussionGroupService.saveGroupAndUpdateQuestion(user,group,memberList,hpqIdList);
        	//添加用户到缓存
    		GroupCache.getInstance().addAll(group.getId(),memberList);
        	return ajaxDoneSuccess(group.getId());
        }catch(Exception e){
        	return ajaxDoneError(this.getText("default.failed"),e);
        }
	}
	
	@RequestMapping(value="/getMembers")
	@ResponseBody
	public Object getMembers(@RequestParam("groupId") String groupId){
		List<DiscussionMember> list=discussionMemberService.findByGroupIdAndNotEqStatus(groupId,MemberStatus.deleted.value());
		CometContext cc=CometContext.getInstance();
		CurrentLoginUser currentLoginUser=CurrentLoginUser.getInstance();
		
		if(list!=null && list.size()>0){
			for(DiscussionMember member:list){
				DiscussionMemberPK pk=member.getId();
				if(cc.getMember(pk.getUserId())!=null&&(currentLoginUser.getMember(pk.getUserId())!=null)){
					member.setStatus(MemberStatus.online.value());
				}else{
					member.setStatus(MemberStatus.offline.value());
				}
			}
		}
		return PageUtil.toAjaxPageResult(list);
	}
	
	
	
	/**
	 * 发送消息
	 * @throws ServletException 
	 * @throws IOException 
	 */
	@RequestMapping(value="/sendToGroup")
	public void sendToGroup(@RequestParam("groupId") String groupId,
			@RequestParam("command") String command,
			@RequestParam("message") String message) throws IOException, ServletException{
		ShiroUser user=this.getCurrentUser();
		instructService.sendToGroup(groupId, user,command, message);
	}
	
	/**
	 * 
	 * @param model
	 * @return
	 */
	@RequestMapping(value="/toSelectStu/{groupId}")
	public String toSelectStu(Model model,@PathVariable("groupId") String groupId){
		String userId=this.getCurrentUserId();
		Btable btable=btableDaoService.findByTeaUserIdAndLessonTime(userId, DateUtil.getNow());
		String clsId=null;
		if(btable!=null){
			clsId=btable.getClaid().getClsId();
		}
		//从班级里选择学生
		List<Student> students= studentService.findByClsId(clsId);
		//已选择的学生
		List<Student> selectedStudents= studentService.findByDiscussionGroupId(groupId);
		Set<String> idList=GroupCache.getInstance().get(groupId);
	
		model.addAttribute("idList",idList);
		
		model.addAttribute("groupId",groupId);
		model.addAttribute("students",students);
		model.addAttribute("selectedStudents",selectedStudents);
		
		return "qso/instruct/selectStudent";
	}
	
	/**
	 * 
	 * 讨论组选中学生
	 * @param model
	 * @param groupId
	 * @param selectIds
	 * @param deSelectIds
	 * @return
	 */
	@RequestMapping(value = "/doSelectStu")
	@ResponseBody
	public AjaxResult doSelectStu(Model model,
			@RequestParam("groupId") String groupId,
			@RequestParam("selectIds") String selectIds,
			@RequestParam("deSelectIds") String deSelectIds) {
		
		ShiroUser user=this.getCurrentUser();
		List<String> selectedList=new ArrayList<String>();
		Collections.addAll(selectedList,StringUtils.split(selectIds,","));
		
		List<String> deSelectedList=new ArrayList<String>();
		Collections.addAll(deSelectedList,StringUtils.split(deSelectIds,","));
		//发送被删除消息到选择的删除学生窗口
		instructService.sendNotify(CometDomain.group,CometCommand.toExit,groupId, user,deSelectedList);

		//需要将deSelectIds中的用户从讨论组用户缓存中清除 ;
		GroupCache.getInstance().removeAll(groupId, deSelectedList);
		//将新选中的用户加入到讨论组
		GroupCache.getInstance().addAll(groupId,selectedList);
		
		List<String> oldList=discussionMemberService.findMemberIdByGroupIdAndNotEqStatus(groupId, MemberStatus.deleted.value());
		//发送更新用户列表通知至现有成员
		instructService.sendNotify(CometDomain.group,CometCommand.updateUserList,groupId, user,oldList);
		//发送邀请通知至选中的学生
		instructService.sendNotify(CometDomain.main,CometCommand.instruct,groupId, user, selectedList);
		discussionGroupService.updateMembers(groupId,selectedList,deSelectedList);
		return ajaxDoneSuccess();
	}



	/**
	 * 学生加入到讨论组(已经被老师加入到组的情况)
	 * 
	 */
	@RequestMapping(value="/joinGroup/{groupId}")
	public String joinGroup(Model model,@PathVariable("groupId") String groupId){
		DiscussionGroup group=discussionGroupService.getOne(groupId);
		model.addAttribute(groupId);
		String vmUserId=group.getVmUserId();
		VmUser vu=vmUserService.findByUserId(vmUserId);
		if(vu==null){
			logger.info(vmUserId+ ":没有分配虚拟机");
		}
		List<String> memberList=discussionMemberService.findMemberIdByGroupIdAndNotEqStatus(groupId, MemberStatus.deleted.value());
		instructService.sendNotify(CometDomain.group,CometCommand.updateUserList,memberList);
    	model.addAttribute("vu",vu);
		return "qso/instruct/instructStu";
	}
	
	/**
	 * 学生主动参与(未被老师加入到组的情况)
	 * 
	 */
	@RequestMapping(value="/initiativeJoin/{groupId}")
	public String initiativeJoin(Model model,@PathVariable("groupId") String groupId){
		ShiroUser user=this.getCurrentUser();
		
		DiscussionGroup group=discussionGroupService.getOne(groupId);

		discussionGroupService.addMember(groupId,user.getId());
		
		List<String> memberList=discussionMemberService.findMemberIdByGroupIdAndNotEqStatus(groupId, MemberStatus.deleted.value());
		
		instructService.sendNotify(CometDomain.group,CometCommand.updateUserList,memberList);
		
		model.addAttribute(groupId);
		String vmUserId=group.getVmUserId();
		VmUser vu=vmUserService.findByUserId(vmUserId);
		if(vu==null){
			logger.info(vmUserId+ ":没有分配虚拟机");
		}
    	model.addAttribute("vu",vu);
		return "qso/instruct/instructStu";
	}
	

	@RequestMapping(value="/toHistoryList")
	public String toHistoryList(){
		return "qso/instruct/historyList";
	}
	
	@RequestMapping(value="/toDetail/{groupId}")
	public String toDetail(Model model,@PathVariable("groupId") String groupId){

		DiscussionGroup group=discussionGroupService.getOne(groupId);
		List<Attachment> attList=attachmentService.findByBusiness(groupId, BusinessType.DISCUSSION_GROUP.getValue());
		List<DiscussionMember> memberList=discussionMemberService.findByGroupId(groupId);
		model.addAttribute("groupId", groupId);
		model.addAttribute("group", group);
		model.addAttribute("attList", attList);
		model.addAttribute("memberList", memberList);
		return "qso/instruct/detail";
	}
	
	
	
	/**
	 * 
	 * 历史资料
	 * @param req
	 * @param groupId
	 * @param file
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/historyList")
	@ResponseBody
	public String historyList(Model model,@ModelAttribute("page") PageParam page,HttpServletRequest req) {
		Map<String, Object> searchParams = Servlets.getParametersStartingWith(req, "search_");
		Page<DiscussionGroup> listPage = discussionGroupService.findPage(DiscussionGroup.class,searchParams,page);
		model.addAttribute("searchParams", Servlets.encodeParameterStringWithPrefix(searchParams, "search_"));
		return PageUtil.toAjaxPageResult(listPage);
	}
	
	/**
	 * 老师将历史资料发送给学生参考,同时将问题状态设置为完成
	 * @param refGroupId 引用资料的groupId
	 * 
	 * @param sendUserIds
	 * @return
	 */
	@RequestMapping(value="/sendReferences")
	@ResponseBody
	public AjaxResult sendReferences(@RequestParam("refGroupId") String refGroupId,@RequestParam("sendIds") String sendIds,@RequestParam("hpqIds") String hpqIds){
		
		ShiroUser user=this.getCurrentUser();
		List<String> userIdList=new ArrayList<String>();
		Collections.addAll(userIdList,StringUtils.split(sendIds,","));
		try{
			//发送资料信息到选择的删除学生窗口
			instructService.sendNotify(CometDomain.main,CometCommand.historicalData,null, user,userIdList,refGroupId);
			String[] idArr=StringUtils.split(hpqIds,",");
			if(idArr.length>0){
				helpQueService.updateHpqStatus(idArr,HelpQueStatus.CO);
			}
			return this.ajaxDoneSuccess();
		}catch(Exception e){
			return this.ajaxDoneError();
		}
	}
    
	/**
	 * 
	 * 注意ajax上传返回Context-Type不能为json(ie下会显示下载窗口)
	 * @param req
	 * @param groupId
	 * @param file
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/upload", method = RequestMethod.POST)
	@ResponseBody
	public String upload(HttpServletRequest req,
			@RequestParam("groupId") String groupId,
			@RequestParam("file") MultipartFile file) throws IOException {

		ShiroUser user=this.getCurrentUser();
		String basePath = req.getSession().getServletContext().getRealPath("/");
		String oriName="";
		String extName="";
		try{
	        if (file!=null && !file.isEmpty()) {
	        	oriName=file.getOriginalFilename();
	        	extName=StringUtil.getExtName(oriName,'.');
	    		Attachment att = new Attachment();
	    		String id=UUID.randomUUID().toString();
	    		att.setId(id);
	    		att.setBusinessId(groupId);
	    		att.setBusinessType(BusinessType.DISCUSSION_GROUP.getValue());
	    		att.setDateCre(DateUtil.getNow());
	    		att.setFileSize(file.getSize());
	    		att.setOriginalName(oriName);
	    		att.setExtName(extName);
	    		String newName=id+"."+extName;
	    		String filePath=WebConstants.UPLOAD_DIR+File.separator+BusinessType.DISCUSSION_GROUP.getValue();
	    		att.setFilePath(filePath+File.separator+newName); 
	    		
	    		String savePath=basePath+File.separator+filePath;
	    		attachmentService.save(att, file, savePath,newName);
	    		
	    		List<String> memberList=discussionMemberService.findMemberIdByGroupIdAndNotEqStatus(groupId, MemberStatus.deleted.value());
	    		//发送更新附件列表通知至讨论组成员
	    		instructService.sendNotify(CometDomain.group,CometCommand.updateAttachmentList,groupId, user,memberList);
	        } 
			return ajaxDoneSuccess(this.getText("save.success")).toString();
		}catch(Exception e){
			return ajaxDoneError(this.getText("save.failed"), e).toString();
		}
	}
	
	
}
